package com.jy.datapipeline.export.task;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
import com.jy.datapipeline.export.entity.ExpTaskExecuteLogModel;
import com.jy.datapipeline.export.service.DataStoreInfoService;
import com.jy.datapipeline.export.service.ExpRuleService;
import com.jy.datapipeline.export.service.ExpTaskExecuteLogService;
import com.jy.datapipeline.export.service.ExpTaskService;
import com.jy.datapipeline.common.util.CronUtils;
import com.jy.datapipeline.export.entity.DataStoreInfoModel;
import com.jy.datapipeline.export.entity.ExpRuleModel;
import com.jy.datapipeline.export.entity.ExpTaskExecuteDetailLogModel;
import com.jy.datapipeline.export.entity.ExpTaskModel;
import com.jy.datapipeline.export.service.ExpTaskExecuteDetailLogService;
import com.jy.datapipeline.common.util.FtpUtil;
import com.jy.datapipeline.common.util.TEAUtil;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class ScheduledTask {
    @Autowired
    private ExpTaskService expTaskService;
    @Autowired
    private ExpTaskExecuteLogService expTaskExecuteLogService;
    @Autowired
    private ExpTaskExecuteDetailLogService expTaskExecuteDetailLogService;
    @Autowired
    private DataStoreInfoService dataStoreInfoService;

    @Autowired
    private ExpRuleService ruleService;
//    @Autowired
//    private JdbcTemplate jdbcTemplate;
    @Value("${config.localStorePath}")
    public   String localStorePath;

    @Value("${config.checkdelayhour}")
    public   int checkdelayhour;

    //@Async("asyncTask2")
    //@Scheduled(cron = "*/5 * * * * ? ")
    public void findExecuTask() {
        try{
            List<Map<String,Object>> taskList= expTaskService.findExecuTask();
            if(taskList.size()>0){
               // log.info("task size {} "+taskList.size());
                taskList.forEach( map ->{String taskId=map.get("task_id")==null?"":map.get("task_id").toString();
                    ExpTaskModel task= this.expTaskService.findByTaskId(taskId);
                    ExpTaskExecuteLogModel etelm=this.expTaskExecuteLogService.startTaskExeucte(task);
                    if(etelm!=null){
                        String netexecuteTime = CronUtils.nextExecution(task.getCrontab());
                        this.expTaskService.updateExpTaskStatus(1, taskId, netexecuteTime);
                       this.expTaskExecuteLogService.executeTask(task,etelm);
                        //更新next时间
//                        if(flag) {
//
//
//                        }
                    }


                });

            }
        }catch (Exception e){
            log.error("findExecuTask error",e);
        }
    }
    //修改任务状态
   // @Scheduled(cron = "*/20 * * * * ? ")
    public void monitorTaskStatusByError(){
        List<ExpTaskExecuteLogModel> expTaskExecuteLogModelList= this.expTaskExecuteLogService.findByStatus(1);
        if(expTaskExecuteLogModelList.size()>0){
            expTaskExecuteLogModelList.forEach( executeLogModelList ->{
              List<ExpTaskExecuteDetailLogModel> list=  this.expTaskExecuteDetailLogService.
                  findBytaskExecutelogLogIdAndExpStatusLessThan(executeLogModelList.getTaskExecuteLogId(),0);
                if(list.size()>0){
                    this.expTaskExecuteLogService.updateExeuceStatus(executeLogModelList.getTaskExecuteLogId(),3,0,"","");
                    this.expTaskService.updateExpTaskStatus(3,executeLogModelList.getTaskId(),"");
                }

            });
        }
    }

//    @Scheduled(cron = "*/30 * * * * ? ")
//    public  void updateTaskStatus(){
//
//    }
    //@Scheduled(cron = "*/20 * * * * ? ")
    public void monitorTaskStatusBySuccess(){
        List<ExpTaskExecuteLogModel> expTaskExecuteLogModelList= this.expTaskExecuteLogService.findByStatus(1);
        if(expTaskExecuteLogModelList.size()>0){
            AtomicInteger successCount= new AtomicInteger();
            expTaskExecuteLogModelList.forEach( executeLogModelList ->{
             List<Map<String,Object>> list=    this.expTaskExecuteDetailLogService.findBytaskExecutelogLogIds(executeLogModelList.getTaskExecuteLogId());
               // List<ExpTaskExecuteDetailLogModel> list=  this.expTaskExecuteDetailLogService.findBytaskExecutelogLogId(executeLogModelList.getTaskExecuteLogId());
                if(list.size()>0){
                    int exp_status=Integer.parseInt( list.get(0).get("exp_status")==null?"0":list.get(0).get("exp_status").toString());
                    //list.forEach( detaillist->{
                        if(exp_status==7){
                            successCount.getAndIncrement();
                        }
                   // });
                    if(successCount.get()==list.size()){
                        this.expTaskExecuteLogService.updateExeuceStatus(executeLogModelList.getTaskExecuteLogId(),2,0,"","");
                        ExpTaskModel taskModel= this.expTaskService.findByTaskId(executeLogModelList.getTaskId());
                        if(taskModel!=null){
                            if(taskModel.getTaskType()==1){
                                this.expTaskService.updateExpTaskStatus(2,executeLogModelList.getTaskId(),"");
                            }
                        }
                    }
                }
            });
        }
    }

    //@Scheduled(cron = "0 */1  * * * ? ")
    public  void restryfileToSftp(){
        List<ExpTaskExecuteDetailLogModel> etedlmList= expTaskExecuteDetailLogService.findByExpStatus(-3,0);//sftp上传error
        if(etedlmList.size()>0){
            AtomicReference<ChannelSftp> channelSftp=new AtomicReference<>();

                etedlmList.forEach( etedl-> {

                    //检查是否有反馈文件
                    DataStoreInfoModel dsim = this.dataStoreInfoService.findByStoreId(
                        etedl.getStoreId());
                    ExpRuleModel expRuleModel= this.ruleService.findByRuleId(etedl.getRuleId());
                    ExpTaskExecuteDetailLogModel expTaskExecuteDetailLogModel = new ExpTaskExecuteDetailLogModel();

                    try {
                        channelSftp.set(FtpUtil.connectBySftp(dsim.getHost(),
                            dsim.getUserName(),
                            TEAUtil.decode(dsim.getPassword())));
                        log.info("retry sftp connection datafile:{}",etedl.getDataFilePath());
                        etedl.setExpStatus(3);//上传中
                        etedl.setSftpStartTime(new Date());
                        expTaskExecuteDetailLogService.updateExpStatus(etedl);
                        if(etedl.getDataFilePath()!=null){
                            String[] dataFilePathStr=etedl.getDataFilePath().split(",");
                            for(int i=0;i<dataFilePathStr.length;i++){
                                //String dataFilePath=dataFilePathStr[i];
                                FtpUtil.uploadFileBySftp(dataFilePathStr[i],dsim.getRemotePath(),
                                    channelSftp.get(), expRuleModel.getIsFile());
                            }
                            String verifyFilePath=localStorePath+"/"+etedl.getDataFileNamePrefix()+".verf";
                            FtpUtil.uploadFileBySftp(verifyFilePath,dsim.getRemotePath(),
                                channelSftp.get(), expRuleModel.getIsFile());
                            FtpUtil.disconnect(channelSftp.get());
                        }

                       // String dataFilePath=localStorePath+"/"+etedl.getDataFileNamePrefix()+".dat";




                        etedl.setExpStatus(4);//上传完成
                        etedl.setSftpeEndtime(new Date());
                        expTaskExecuteDetailLogService.updateExpStatus(etedl);
                        expTaskExecuteLogService.updateExeuceStatus(etedl.getTaskExecutelogLogId(),1,0,"","");
                    } catch (JSchException | SftpException e) {
                        log.info("retry sftp error ",e);
                        etedl.setErrorMsg(e.getMessage());
                        etedl.setExpStatus(-3);//上传异常
                        etedl.setSftpeEndtime(new Date());
                        expTaskExecuteDetailLogService.updateExpStatus(etedl);
                        FtpUtil.disconnect(channelSftp.get());
                    }

                });
            }
    }
    //@Async("asyncTask2")
   // @Scheduled(cron = "0 */10 * * * ? ")
    public  void checkFeedback(){
        AtomicReference<ChannelSftp> channelSftp=new AtomicReference<>();
        AtomicReference<List<String>> fileList=new AtomicReference<>();
        try{
            //查询上传完成的文件

            List<ExpTaskExecuteDetailLogModel> etedlmList= expTaskExecuteDetailLogService.findByExpStatus(4,checkdelayhour);//sftp上传完成
            if(etedlmList.size()>0){
                DataStoreInfoModel dsim= this.dataStoreInfoService.findByStoreId(etedlmList.get(0).getStoreId());

                log.info("checkFeedback start file length: {} ",etedlmList.size());
                if(channelSftp.get()==null){
                    channelSftp.set(FtpUtil.connectBySftp(dsim.getHost(), dsim.getUserName(),
                        TEAUtil.decode(dsim.getPassword())));
                }

                etedlmList.forEach( etedl->{
                    //检查是否有反馈文件

                   // String OkFilepath=dsim.getRemotePath()+"/"+etedl.getDataFileNamePrefix()+".ok";
                    //log.info("开始清除文件==>"+OkFilepath);
                    String verifyFilepath=dsim.getRemotePath()+"/"+etedl.getDataFileNamePrefix()+".verf";
                    try {

//                        if(fileList.get()==null){
//                            fileList.set(
//                                FtpUtil.getSftpFileList(dsim.getRemotePath(), channelSftp.get()));
//                        }
                       String OkResult="";
                       String verifyResult="";
                       // if(fileList!=null && fileList.get().size()>0){
                          //  for (String file: fileList.get()){
                                String okfileName=etedl.getDataFileNamePrefix()+".ok";
                                String verifyName=etedl.getDataFileNamePrefix()+".verf";
//                                if(file.equals(okfileName)){
                                    OkResult=FtpUtil.readFileBySftp(channelSftp.get(),dsim.getRemotePath(),okfileName);
                                   // fileList.get().remove(file);
//                                }
//                                if(file.equals(verifyName)){
                                    verifyResult=FtpUtil.readFileBySftp(channelSftp.get(),dsim.getRemotePath(),verifyName);
                                   // fileList.get().remove(file);
//                                }
//                            }
//                        }
                        if (OkResult != null && !OkResult.equals("")) {
                            log.info("check feedback verifyResult {} OkResult {} ",verifyFilepath,OkResult);
                            if(OkResult.equals(verifyResult)){
                                //反馈成功
                                etedl.setExpStatus(5);//反馈成功
                                etedl.setFeedbackTime(new Date());
                                this.expTaskExecuteDetailLogService.updateExpStatus(etedl);
                                String dataFilePathPreff=etedl.getDataFilePath().split("\\.")[0];
                                //删除本地文件
                                File datefile=new File(etedl.getDataFilePath());
                                File verifyfile=new File(dataFilePathPreff+".verf");
                                if(datefile.isFile() && verifyfile.isFile()){
                                    datefile.delete();
                                    verifyfile.delete();
                                }
                                //远程删除
                                String sftpDateFilePath=etedl.getDataFileNamePrefix()+".dat";
                                String sftpVerifyFilePath=etedl.getDataFileNamePrefix()+".verf";
                                String sftpOkFilePath=etedl.getDataFileNamePrefix()+".ok";
                                FtpUtil.deleteFile(channelSftp.get(),dsim.getRemotePath(),sftpDateFilePath);
                                FtpUtil.deleteFile(channelSftp.get(),dsim.getRemotePath(),sftpVerifyFilePath);
                                FtpUtil.deleteFile(channelSftp.get(),dsim.getRemotePath(),sftpOkFilePath);
                                ;
                                etedl.setExpStatus(7);//反馈成功
                                etedl.setDeleteTime(new Date());
                                this.expTaskExecuteDetailLogService.updateExpStatus(etedl);
                                //
                                this.expTaskExecuteLogService.updateExeuceStatus(etedl.getTaskExecutelogLogId(),2,0,"","");

                                this.expTaskService.updateExpTaskStatus(2,etedl.getTaskId(),"");
                            }

                        }


                    } catch (JSchException | SftpException e) {
                        log.info(verifyFilepath);

                        //this.expTaskExecuteLogService.updateExeuceStatus(etedl.getTaskExecutelogLogId(),-1);
                        log.error("SftpException  ",e);
                    }

                });


            }
        }
        catch (Exception e){
            log.error("Exception ",e);
        }finally {
            if (  channelSftp.get()!=null){
                FtpUtil.disconnect(channelSftp.get());

            }
        }

    }

    public static void main(String[] args) {
        //to_date(#system.YYYYMM#||'010000','YYYYMMDDHH24MISS')
        //to_date('#system.YYYYMM#'||'01000000','YYYYMMDDHH24MISS')
        //TO_DATE('#system.YYYYMMDD#','YYYYMMDD') AND OFFER_ID IN(100200020001,100200020002,100200020003,100200020004,100200020005,100200020006,100200020007,100200020008) AND USER_TYPE_ID = 2
   //     String paramsStr="VALID_DATE <= TO_DATE('#system.YYYYMMDD#','YYYYMMDD') AND OFFER_ID IN(100200020001,100200020002,100200020003,100200020004,100200020005,100200020006,100200020007,100200020008) AND USER_TYPE_ID = 2";

//        int start=paramsStr.indexOf("#");
//        int end=paramsStr.lastIndexOf("#")+1;
//        String paramsStr2= paramsStr.substring(start,end);
//        int start2=paramsStr2.indexOf(".")+1;
//        int end2=paramsStr2.lastIndexOf("#");
//        String formatStr=paramsStr2.substring(start2,end2);
//        String result=paramsStr.replaceAll(paramsStr2,DateUtils.formatDate(new Date(),formatStr));
//        System.out.println(result);
//        String tbleStr="acce_sale_regi_f_201611";
//
//        String tblStr=tbleStr.substring(0,tbleStr.lastIndexOf("_"));
//        System.out.println(tblStr);
//        String str="CRMHB_so5_ins_srvpkg_f_392_20221019_0001";
//        str=str.toUpperCase(Locale.ROOT);
//        System.out.println(str);
//       StringBuilder str=new StringBuilder();
//        str.append("11111\n");
//        str.append("2222\r\n");
//        str.append("33333\n\r");
//        str.append("444444\r");
//        str.append("555555\r");
//        System.out.println("befor:==>"+str.toString());
//        System.out.println("after:==>"+str.toString().replaceAll("\\n|\\r",""));
    }
}
